package com.lineengine.lineengine.node;


import com.lineengine.lineengine.common.CommonErrorCode;
import com.lineengine.lineengine.common.ErrorType;
import com.lineengine.lineengine.context.IContext;
import com.lineengine.lineengine.result.DefaultResult;
import com.lineengine.lineengine.result.IResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * AbstractRollbackNode
 *
 * @author wenrong.yu
 */
public abstract class AbstractRollbackNode<T extends IContext<T>> extends AbstractNode<T> implements IRollback<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRollbackNode.class);

    @Override
    public IResult<T> execute(T context) {
        return processWithRecordCostTime(context, () -> {
            try {
                IResult<T> result = doExecute(context);
                if (!result.isSuccess()) {
                    this.rollback(context);
                }
                return result;
            } catch (Exception e) {
                LOGGER.warn("Occurs Exception, start to rollback.", e);
                this.rollback(context); // 异常回滚


                return DefaultResult.fail(ErrorType.SERVER, CommonErrorCode.INTERNAL_SERVER_ERROR);
            }
        });
    }

    @Override
    public void rollback(T context) {
        LOGGER.warn("Mark this context rollback flag as true.");
        context.markRollback();
    }
}
